﻿using System;
using System.Text;
using System.Threading.Tasks;
using Best.SmartCms.Core.Utility;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Best.SmartCms.Domain;
using Best.SmartCms.Utility;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;

namespace Best.SmartCms.API.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    public class CheckStatusController : Controller
    {
        /// <summary>
        /// 
        /// </summary>
        public enum SystemFailureFlags
        {
            /// <summary>
            /// 
            /// </summary>
            NONE = 0,
            /// <summary>
            /// 
            /// </summary>
            检查数据库状态时发生异常 = 32768,
            /// <summary>
            /// 
            /// </summary>
            检查页面访问时发生异常 = 131072,
            /// <summary>
            /// 
            /// </summary>
            获取客户AUTOCOMPLETE失败 = 32,
            /// <summary>
            /// 
            /// </summary>
            检查WS时发生异常 = 524288,
            /// <summary>
            /// 
            /// </summary>
            检查页面访问失败 = 65536
        }

        private SystemFailureFlags statusCode = SystemFailureFlags.NONE;
        private bool status = true;

        /// <summary>
        /// 
        /// </summary>
        protected MySqlDbContext MySqlDbContext;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mySqlDbContext"></param>
        public CheckStatusController(MySqlDbContext mySqlDbContext)
        {
            MySqlDbContext = mySqlDbContext;
        }

        /// <summary>
        /// 系统状态检查
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet]
        [Route("CheckSystemStatus")]
        public async Task<string> CheckSystemStatus()
        {
            var sb = new StringBuilder();

            try
            {
                sb.Append(AppendNormalMessage("<div style=\"font-weight: bold; font-size: 14px;\">LSJ系统检查</div><hr />"));
                sb.Append(AppendNormalMessage("开始检查系统状态......"));
                sb.Append(await CheckDb().ConfigureAwait(false));
                sb.Append(await CheckWebPage().ConfigureAwait(false));
                var result = status ? "通过" : "不通过";
                sb.Append(AppendErrorMessage(string.Format("系统状态检查完成，结果为[{0}]，错误代码是[{1}]", result, statusCode), status ? "blue" : "red"));
            }
            catch (Exception ex)
            {
                sb.Append(AppendErrorMessage(string.Format("检查程序出现异常，无法继续，错误消息：{0}<br />错误堆栈：{1}", ex.Message, ex.StackTrace)));
            }

            return sb.ToString();
        }

        private string AppendNormalMessage(string msg)
        {
            return string.Format("{0}  {1}<br />", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), msg);
        }

        private string AppendErrorMessage(string msg)
        {
            return string.Format("<span style='color:red;'>{0}  {1}</span><br />", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), msg);
        }

        private string AppendErrorMessage(string msg, string color)
        {
            return string.Format("<span style='color:{2};'>{0}  {1}</span><br />", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), msg, color);
        }

        private async Task<string> CheckDb()
        {
            var sb = new StringBuilder();
            try
            {
                // check base data db
                var maxSyncVersion = await MySqlDbContext.CheckDbSet.AsNoTracking().MaxAsync(t => t.Gid).ConfigureAwait(false);
                if (maxSyncVersion > 0)
                {
                    sb.Append(AppendNormalMessage("访问Mysql数据库正常"));
                }
            }
            catch (Exception ex)
            {
                statusCode = statusCode | SystemFailureFlags.检查数据库状态时发生异常;
                sb.Append(AppendNormalMessage("检查数据库状态时发生异常：" + ex.Message));
                NLogManager.LogError(ex);
                status = false;
            }

            return sb.ToString();
        }

        private async Task<string> CheckWebPage()
        {
            var sb = new StringBuilder();

            try
            {
                sb.Append(await HttpWebRequestCheck(new Uri(new Uri(Request.GetDisplayUrl()), "SyncTime.ashx").ToString(), DateTime.Now.Year.ToString(), false, "检查页面访问正常", SystemFailureFlags.检查页面访问失败).ConfigureAwait(false));
            }
            catch (Exception ex)
            {
                statusCode = statusCode | SystemFailureFlags.检查页面访问时发生异常;
                sb.Append(AppendErrorMessage(SystemFailureFlags.检查页面访问时发生异常 + "：" + ex.Message));
                status = false;
            }

            return sb.ToString();
        }

        private async Task<string> HttpWebRequestCheck(string url, string checkString1, bool showReturnValue, string successMsg, SystemFailureFlags flag)
        {
            var sb = new StringBuilder();
            try
            {
                sb.Append(AppendNormalMessage("访问URL：" + url));
                var client = HttpRequestHelper.CreateHttpClient(3000);
                var response = await client.GetStringAsync(url).ConfigureAwait(false);
                if (response.Contains(checkString1))
                {
                    string returnValue = string.Format("{1}，返回<xmp>{0}</xmp>", response, successMsg);
                    if (!showReturnValue)
                        returnValue = string.Format("{0}", successMsg);
                    sb.Append(AppendNormalMessage(returnValue));
                }
                else
                {
                    statusCode = statusCode | SystemFailureFlags.获取客户AUTOCOMPLETE失败;
                    sb.Append(AppendErrorMessage(string.Format("{0}，预期包含[{2}]，结果返回<xmp>{1}</xmp>", SystemFailureFlags.检查WS时发生异常, response, checkString1)));
                    status = false;
                }
            }
            catch (Exception ex)
            {
                statusCode = statusCode | flag;
                sb.Append(AppendErrorMessage(flag + "：" + ex.Message));
                status = false;
            }
            return sb.ToString();
        }
    }
}
